#include "unp.h"
#include "user.h"


int main(int argc,char **argv)
{
	int 			i,maxi,maxfd,listenfd,connfd,sockfd;
	int 			nready;
	int 			client[FD_SETSIZE];
	ssize_t			n;
	fd_set			rset,allset;
	char			line[MAXLINE];
	socklen_t		clilen;
	struct sockaddr_in	cliaddr,servaddr;
	
	int 			groups_ids[5];
	struct user		users[5];
	int 			flag;

	void relay_message(struct user *u,int  *group_fds,int *group_ids,int *num,fd_set *set );
	int  register_user(struct user *u,int id , int socket);
	void inform(struct user *u,int *group_fds,int *group_ids,int *num,fd_set *set,int flag);

	listenfd = Socket(AF_INET,SOCK_STREAM,0);

	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family		= AF_INET;
	servaddr.sin_addr.s_addr	= htonl(INADDR_ANY);
	servaddr.sin_port		= htons(SERV_PORT);

	Bind(listenfd,(SA * )&servaddr,sizeof(servaddr));

	Listen(listenfd,LISTENQ);

	maxfd = listenfd;
	maxi = -1;
	for(i=0;i<FD_SETSIZE;i++)
		client[i]=-1;
	for (i=0;i<5;i++)
	{
		users[i].socket = -1;
		users[i].group_id = -1;
		users[i].user_id = -1;
		groups_ids[i] = -1;
	}
	FD_ZERO(&allset);
	FD_SET(listenfd,&allset);

	for(;;)
	{
		flag=0;
		rset = allset;
		nready = Select(maxfd+1,&rset,NULL,NULL,NULL);

		if(FD_ISSET(listenfd,&rset))
		{
			clilen = sizeof(cliaddr);
			connfd = Accept(listenfd,(SA *)&cliaddr,&clilen);
					

			for(i=0;i<FD_SETSIZE && i<5;i++)
			{	
				if(client[i]<0)
				{
					
					
					client[i]=connfd;
					users[i].socket = connfd;
					printf("The NO.%d User is join the",i);
					inform(users+i,client,groups_ids,&maxi,&allset,0);
					if(flag=(register_user(users+i,i+1,connfd))==1)
					{
						groups_ids[i] = users[i].group_id;
						printf(" group %d\n",groups_ids[i]);
					

						printf("No. %d User %s has join the group\n\n",i+1,users[i].name);
						inform(users+i,client,groups_ids,&maxi,&allset,flag);
					}	
					else 
					{
						err_sys("registe error!");
					}
					break;
				}
			}

			if(i == FD_SETSIZE && i==5)
				err_quit("too many clients");

			FD_SET(connfd,&allset);
			if(connfd>maxfd)
				maxfd = connfd;
			if(i>maxi)
				maxi= i;
			if(--nready<=0)
				continue;
		}

		for(i=0;i<=maxi;i++)
		{
			if( users[i].socket<0)
				continue;
			
			if(FD_ISSET(users[i].socket,&rset))
			{
				relay_message(users+i,client,groups_ids,&maxi,&allset);
				if(--nready <=0)
					break;
			}
		}
	}
}
